<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // then方法是一个异步方法，且是一个异步微任务；
    /*
        任务：可以分为同步任务和异步任务
            同步任务：会优先与异步任务执行，并且依次执行
            异步任务：会在同步任务执行完毕之后排队执行
    */
    // setTimeout(() => {
    //   console.log(111);
    // });
    // setTimeout(() => {
    //   console.log(222);
    // });
    // console.log(333);
    // 执行队列是3 1 2

    console.log(111);
    setTimeout(() => {
      console.log(555);
    });
    let p = new Promise(resolve => {
      console.log(222);
      resolve();
    })
    p.then(() => {
      console.log(333);
    })
    console.log(444);
    /*
      同步任务：1 2 4 会优先按顺序执行
      异步任务：5 3 后执行
      实际执行队列是：1 2 4 3 5
    */
    /*
      同步和异步
      同步代码会先执行
      异步：分为微任务和宏任务
          1.微任务：为了提高js的响应精度，缩小js的执行颗粒度。
          // 微任务可以被插队
          [1] [2] [3] [4] [5] [6] ----->微任务队列
                   |[7]  可以插队
          异步中的微任务：promise.then()方法，和MutationObserve()方法监听节点变化的。

          2.宏任务：普通js任务都是宏任务
          // 宏任务需要排队依次执行，不能插队
          [1] [2] [3] [4] [5] [6] ----->宏任务队列
                   |              [7]  不能插队
          事件执行  资源加载  ajax  定时器  ...主线程 （整体的script）

      微任务和宏任务的执行顺序
      // 系统内部会先执行宏任务，然后再执行微任务
      // 每个宏任务执行完毕后会进入微任务检查点，检查宏任务下的微任务队列，如果队列为空就继续执行下一个宏任务，如果不为空就执行完毕微任务队列
      【宏1->[微1,微2]】----》【宏2->[微1,微2,微3]】----》【宏3->[微1,微2]】----》【宏4->[微1,微2,微3]】----》【宏5->[微1,微2]】

      // 宏任务里有一个任务是script主线程任务（会执行所有的同步代码）；
      // 广义上来说，同步代码也是异步代码
      【srcipt里的同步代码：1,2,4 [微任务队列：then微任务-3]】 ----》【settimeout宏任务执行-5[空]】;
    */
  </script>
</body>

</html>